/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.npmpackagepatch;

import com.inspur.edp.web.npmpackagepatch.packagejson.PackageJsonInfo;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * npm包集成补丁工具
 *
 * @author noah
 */
public class NpmPackagePatchService {
    /**
     * 补丁工具调用入口
     *
     * @param param
     */
    public void Update(HashMap<String, String> param) {
        System.out.println("开始执行npm包版本更新");
        if (param == null) {
            throw new RuntimeException("npm包安装入参param 为空");
        }
        String patchPKG = param.get("PatchPkg");
        String serverPath = param.get("ServerPath");

        // 补丁路径为空或serverPath 为空都是不允许的
        if (patchPKG == null || patchPKG.length() == 0) {
            throw new RuntimeException("npm包安装入参，补丁路径参数PatchPKG 为空");
        }
        if (serverPath == null || serverPath.length() == 0) {
            throw new RuntimeException("npm包安装入参，安装环境路径参数ServerPath 为空");
        }

        File patchFile = new File(patchPKG);
        // 如果目录不存在  那么不需要执行任何操作
        if (!patchFile.exists()) {
            return;
        }

        // 从server读取package.json 作为临时文件
        Path serverPackageJsonPath;
        // 如果server目录不存在  那么认为是包含jstack目录
        if (new File(Paths.get(serverPath).resolve("server").toString()).exists()) {
            serverPackageJsonPath = Paths.get(serverPath).resolve("server").resolve("runtime").resolve("nodejs").resolve("packagejson");
        } else {
            serverPackageJsonPath = Paths.get(serverPath).resolve("jstack").resolve("runtime").resolve("nodejs").resolve("packagejson");
        }

        File serverPackageJsonFilePath = new File(serverPackageJsonPath.resolve(PatchConstants.PackageJsonFileName).toString());
        if (!serverPackageJsonFilePath.exists()) {
            System.out.println("server不存在package.json，不更新npm包版本");
            return;
        }

        // 读取补丁文件中特定路径下的json文件
        Path packageJsonPath = Paths.get(patchPKG, "root", "server", "var", "npmpackage");
        File packageJsonPathFileInfo = new File(packageJsonPath.toString());
        // 如果没有包含json文件 那么不需要任何操作
        if (!packageJsonPathFileInfo.exists()) {
            return;
        }
        File tempPackageJsonFilePath = null;
        try {
            // 创造一个临时目录文件
            tempPackageJsonFilePath = copyTempPackageJsonFile(serverPackageJsonPath, serverPackageJsonFilePath);
            String packageJsonInfoContent = FileOperation.readAsString(tempPackageJsonFilePath.getPath());
            PackageJsonInfo packageJsonInfo = SerializePackageJson.getInstance().deserialize(packageJsonInfoContent);
            // 版本加1
            packageJsonInfo.versionPlus();

            //读取目录下所有的json文件
            List<File> fileList = new ArrayList<>();
            RescureReadFiles.getFiles(packageJsonPath.toString(), fileList);

            // 只读取server/var/npmpackage 目录下的json文件内容
            // 只读取json文件
            // 判断是否需要更新源文件
            if (fileList.size() > 0) {
                fileList.forEach(t -> {
                    if (t.getName().contains(".json")) {
                        executeSpecialJsonFile(packageJsonInfo, t);
                    }
                });
            }
            PackageJsonFileManager.write(packageJsonInfo, tempPackageJsonFilePath.getPath());

            FileOperation.copyFile(tempPackageJsonFilePath, serverPackageJsonFilePath);


        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex.getMessage(), ex);
        } finally {
            // 临时文件删除
            if (tempPackageJsonFilePath != null && tempPackageJsonFilePath.exists()) {
                tempPackageJsonFilePath.delete();
            }
            System.out.println("npm包版本更新完毕");
        }
    }

    /**
     * 处理具体的json文件
     *
     * @param packageJsonInfo
     * @param t
     */
    private void executeSpecialJsonFile(PackageJsonInfo packageJsonInfo, File t) {
        String patchJsonContent = FileOperation.readAsString(t.getPath());
        PackageJsonInfo specialPackageJsonInfo = SerializePackageJson.getInstance().deserialize(patchJsonContent);
        PackageJsonFileManager.merge(packageJsonInfo, specialPackageJsonInfo);
    }

    private File copyTempPackageJsonFile(Path serverPackageJsonPath, File serverPackageJsonFilePath) {
        File tempPackageJsonFilePath = new File(serverPackageJsonPath.resolve(PatchConstants.TempPackageJsonFileName).toString());

        FileOperation.copyFile(serverPackageJsonFilePath, tempPackageJsonFilePath);
        if (!tempPackageJsonFilePath.exists()) {
            tempPackageJsonFilePath = serverPackageJsonFilePath;
        }
        return tempPackageJsonFilePath;
    }


}
